using System;
using System.Collections.Generic;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;

namespace Chimp.Core
{
    public class ChimpWidget : ChimpBase
    {
        //public Vector2 Pos { get; set; }
        //public Vector2 Size { get; set; }
        private readonly Dictionary<Key, bool> LastKey = new Dictionary<Key, bool>();
        private readonly bool[] TmpBut = new bool[255];
        public float AlphaSpeed = 0.01f;
        public float ColorSpeed = 0.02f;
        public bool Entered;
        public bool NoRender;

        public ChimpWidget(Vector2 pos, Vector2 size, ChimpWidget p)
        {
            Pos = pos;
            Size = size;
            if (p != null)
            {
                Parent = p;
                p.Widgets.Add(this);
                p.Nodes.Add(this);
            }
            Text = "";
            Alpha = 0.0f;
            Color = Color4.Black;
            TargetAlpha = 0.6f;
            TargetColor = new Color4(0.35f, 0.35f, 0.35f, 0.35f);
            Widgets = new List<ChimpWidget>();
        }

        public ChimpWidget Parent { get; set; }
        public List<ChimpWidget> Widgets { get; set; }
        public float Alpha { get; set; }
        public float TargetAlpha { get; set; }
        public Color4 Color { get; set; }
        public Color4 TargetColor { get; set; }
        public string Text { get; set; }

        public Vector2 GlobalPos
        {
            get
            {
                Vector2 pv = Vector2.Zero;
                if (Parent != null)
                {
                    pv = Parent.GlobalPos;
                }
                return Pos + pv;
            }
        }

        public float GlobalAlpha
        {
            get
            {
                float a = 1.0f;
                if (Parent != null)
                {
                    a = Parent.GlobalAlpha;
                }
                return a*Alpha;
            }
        }

        public string NotifyParent(string id, string msg, ChimpWidget w, params object[] dat)
        {
            string pc = "";
            if (Parent != null)
            {
                pc = Parent.NotifyParent(id, msg, w, dat);
            }
            return pc + OnNotify(id, msg, w, dat);
        }

        public virtual string OnNotify(string id, string msg, ChimpWidget w, params object[] dat)

        {
            return "";
        }

        public void UpdateWidget()
        {
            float r = Color.R + (TargetColor.R - Color.R)*ColorSpeed;
            float g = Color.G + (TargetColor.G - Color.G)*ColorSpeed;
            float b = Color.B + (TargetColor.B - Color.B)*ColorSpeed;

            Color = new Color4(r, g, b, 1.0f);

            Alpha += (TargetAlpha - Alpha)*AlphaSpeed;


            foreach (ChimpWidget w in Widgets.ToArray())
            {
                w.UpdateWidget();
            }
        }

        public virtual void OnEnter()
        {
        }

        public virtual void OnExit()
        {
        }

        public virtual void OnWithin()
        {
        }

        public virtual void OnMouseMove(float x, float y, float xi, float yi)
        {
        }

        public virtual void OnMouseDown(int b)
        {
        }

        public virtual void OnMouseUp(int b)
        {
        }

        public virtual void OnMouse(int b)
        {
        }

        public virtual void OnKeyDown(Key key)
        {
        }

        public virtual void OnKeyUp(Key key)
        {
        }

        public virtual void OnKey(Key key)
        {
        }

        public void CheckKey(Key k)
        {
            if (ChimpI.IsKeyDown(k))
            {
                if (!LastKey.ContainsKey(k))
                {
                    OnKeyDown(k);
                    LastKey.Add(k, true);
                }
                OnKey(k);
            }
            else
            {
                if (LastKey.ContainsKey(k))
                {
                    OnKeyUp(k);
                    LastKey.Remove(k);
                }
            }
        }

        public bool UIUpdate()
        {
            foreach (ChimpWidget w in Widgets)
            {
                if (w.UIUpdate())
                {
                    return true;
                }
            }

            if (!PointInsideWidget(ChimpUI.MX, ChimpUI.MY))
            {
                if (ChimpUI.Over == this)
                {
                    OnExit();
                    ChimpUI.Over = null;
                }
                return false;
            }

            if (ChimpUI.Over != this)
            {
                OnEnter();
                if (ChimpUI.Over != null)
                {
                    ChimpUI.Over.OnExit();
                    ChimpUI.Over = null;
                }
                ChimpUI.Over = this;
            }
            else
            {
                OnWithin();
            }

            CheckKey(Key.A);
            CheckKey(Key.B);
            CheckKey(Key.C);
            CheckKey(Key.D);
            CheckKey(Key.E);
            CheckKey(Key.F);
            CheckKey(Key.G);
            CheckKey(Key.H);
            CheckKey(Key.I);
            CheckKey(Key.J);
            CheckKey(Key.K);
            CheckKey(Key.L);
            CheckKey(Key.M);
            CheckKey(Key.N);
            CheckKey(Key.O);
            CheckKey(Key.P);
            CheckKey(Key.Q);
            CheckKey(Key.R);
            CheckKey(Key.S);
            CheckKey(Key.T);
            CheckKey(Key.U);
            CheckKey(Key.V);
            CheckKey(Key.W);
            CheckKey(Key.X);
            CheckKey(Key.Y);
            CheckKey(Key.Z);
            CheckKey(Key.ShiftLeft);
            CheckKey(Key.ShiftRight);
            CheckKey(Key.Space);
            CheckKey(Key.Enter);
            CheckKey(Key.Delete);
            CheckKey(Key.BackSpace);
            CheckKey(Key.Comma);
            CheckKey(Key.Period);
            CheckKey(Key.Number0);
            CheckKey(Key.Number1);
            CheckKey(Key.Number2);
            CheckKey(Key.Number3);
            CheckKey(Key.Number4);
            CheckKey(Key.Number5);
            CheckKey(Key.Number6);
            CheckKey(Key.Number7);
            CheckKey(Key.Number8);
            CheckKey(Key.Number9);
            CheckKey(Key.Minus);
            CheckKey(Key.Plus);
            CheckKey(Key.Slash);
            CheckKey(Key.Left);
            CheckKey(Key.Right);
            CheckKey(Key.Up);
            CheckKey(Key.Down);

            for (int i = 0; i < 3; i++)
            {
                if (ChimpUI.BUT[i] && !TmpBut[i])
                {
                  
                    OnMouseDown(i);
                    ChimpUI.Push[0] = this;
                }

                TmpBut[i] = ChimpUI.BUT[i];
            }


            return OnUpdate(Vector2.Zero);
        }

        private void DoMouseMove()
        {
            OnMouseMove(ChimpUI.MX - GlobalPos.X, ChimpUI.MY - GlobalPos.Y, ChimpUI.XI, ChimpUI.YI);
        }

        public void UIRender()
        {
            if (!NoRender)
            {
                ChimpUI.Handler.OnBeforeRender(this);
                OnRender();
                ChimpUI.Handler.OnAfterRender(this);
            }
            for (int i = 0; i < Widgets.Count; i++)
            {
                Widgets[Widgets.Count - 1 - i].UIRender();
            }
        }

        public virtual bool PointInsideWidget(float x, float y)
        {
            Vector2 gp = GlobalPos;
            if (x >= gp.X && y >= gp.Y && x <= (gp.X + Size.X) && y <= (gp.Y + Size.Y))
            {
                return true;
            }
            return false;
        }

        public override bool OnUpdate(Vector2 pos)
        {
            if (Parent == null)
            {
                UpdateWidget();
            }
            return true;
        }

        public virtual void OnRender()
        {
        }

        public virtual void OnSceneRender()
        {
        }

        public override void OnDraw(Vector2 pos)
        {
            OnSceneRender();
        }
    }
}